#pragma once

#include <memory>
#include <unordered_map>
#include "base/Bytes.h"
#include "protocol/transport.pb.h"
#include "ProtocolCodec.h"
#include "RequestHandler.h"


namespace zeroplus::mq
{
    // ---------------------- 服务端分发器 ----------------------
    class RequestDispatcher
    {
    private:
        std::unordered_map<transport::RequestCode, std::unique_ptr<RequestHandler>> handlers_;

    public:
        template <transport::RequestCode Code, typename Req, typename Resp>
        void RegisterHandler(typename TemplateRequestHandler<Req, Resp>::HandlerFunc handler)
        {
            handlers_[Code] = std::make_unique<TemplateRequestHandler<Req, Resp>>(handler);
        }

        std::optional<transport::ReplyCommand> Process(const transport::RequestCommand &cmd)
        {
            auto it = handlers_.find(cmd.code());
            if (it == handlers_.end())
            {
                return BuildDefaultError();
            }
            return it->second->Handle(Bytes::from_string(cmd.body()));
        }

    private:
        std::optional<transport::ReplyCommand> BuildDefaultError()
        {
            transport::ReplyCommand reply;
            reply.set_code(transport::ResponseCode::UNKNOWN_TYPE);
            return reply;
        }
    };
}